package xyz.eden.gateway.springcloud.admin.component.route;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

@Slf4j
public abstract class AbstractDynamicRouteService implements DynamicRouteService {

    @Resource
    private DynamicRouteOperate dynamicRouteOperate;

    @PostConstruct
    @Override
    public void init() {

        /**
         * 1. 前置处理
         */
        log.info("[Dynamic Route] - [step 1] prefix Operation begin.");
        boolean prefixOperationResult = this.prefixOperation();
        log.info("[Dynamic Route] - [step 1] prefix Operation end, result: [{}].", prefixOperationResult);
        if (!prefixOperationResult) {
            throw new RuntimeException("Prefix Operation Exception");
        }

        /**
         * 2. 获取配置
         */
        log.info("[Dynamic Route] - [step 2] get RouteDefinition Config begin.");
        List<RouteDefinition> routeDefinitionList = this.getRouteDefinitionConfig();
        log.info("[Dynamic Route] - [step 2] get RouteDefinition Config end.");

        /**
         * 3. 更新路由定义
         */
        log.info("[Dynamic Route] - [step 3] update RouteDefinition begin.");
        boolean updateRouteDefinitionResult = this.addRouteConfigInfo(routeDefinitionList);
        log.info("[Dynamic Route] - [step 3] update RouteDefinition end, result: [{}].", updateRouteDefinitionResult);
        if (!updateRouteDefinitionResult) {
            throw new RuntimeException("Update RouteDefinition Exception");
        }

        /**
         * 4. 后置操作
         */
        log.info("[Dynamic Route] - [step 4] update RouteDefinition begin.");
        boolean postOperationResult = this.postOperation();
        log.info("[Dynamic Route] - [step 4] update RouteDefinition end, result: [{}].", postOperationResult);
        if (!postOperationResult) {
            throw new RuntimeException("Post Operation Exception");
        }
    }

    protected boolean addRouteConfigInfo(List<RouteDefinition> routeDefinitionList) {
        return dynamicRouteOperate.saveRouteDefinition(routeDefinitionList);
    }

    protected boolean handleRouteConfigInfo(List<RouteDefinition> routeDefinitionList) {
        return dynamicRouteOperate.updateRouteDefinition(routeDefinitionList);
    }

    /**
     * 前置处理
     */
    protected abstract boolean prefixOperation();

    /**
     * 后置操作
     */
    protected abstract boolean postOperation();
}
